﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Collections;

namespace belov_test
{
    public partial class MainForm : Form
    {
        private const int DEFAULT_TEST_TIME = 600;
        private const int DEFAULT_TIMER_X = 540;
        private const int DEFAULT_TIMER_Y = 610;

        private delegate void CreateMenuDelegate();
        private delegate void RestartTestDelegate();

        private InformationPanel m_infoPanel;
        private AuthorizationForm m_authForm;
        private UserInfo m_userInfo;
        private Questions m_questions;
        private UserPanel m_userPanel;
        private string m_beginTestTime;
        private DateTime m_beginTestTimestamp;
        private AdminPanel m_adminPanel;

        public MainForm()
        {
            InitializeComponent();
        }

        private void OnLoaded(object sender, EventArgs e)
        {
            this.Visible = false;
            CreateAuthForm();
        }

        private void CreateAuthForm()
        {
            m_authForm = new AuthorizationForm();
            m_authForm.UserAuth += new AuthorizationForm.UserAuthEventHandler(OnUserAuth);
            m_authForm.AdminAuth += new AuthorizationForm.AdminAuthEventHandler(OnAdminAuth);
            m_authForm.ShowDialog(this);
        }

        private void CreateAdminPanel(String adminLogin)
        {
            m_adminPanel = new AdminPanel(adminLogin);
            m_adminPanel.Width = ClientSize.Width;
            m_adminPanel.Height = ClientSize.Height - m_infoPanel.Height;
            Controls.Add(m_adminPanel);
        }

        private void CreateUserPanel()
        {
            m_userPanel = new UserPanel(m_userInfo);
            m_userPanel.Width = ClientSize.Width;
            m_userPanel.Height = ClientSize.Height - m_infoPanel.Height;

            Form prompt = new Form();
            prompt.Text = "Статистика по пройденным тестам";
            prompt.Width = 600;
            prompt.Height = 590;
            prompt.FormBorderStyle = FormBorderStyle.Fixed3D;
            NumericUpDown inputBox = new NumericUpDown() { Left = 50, Top = 50, Width = 400 };
            prompt.Controls.Add(m_userPanel);
            prompt.ShowDialog();
        }

        private void OnShowPreviousTest(object sender, EventArgs e)
        { 
            m_userPanel = new UserPanel(m_userInfo);
            m_userPanel.Width = ClientSize.Width;
            m_userPanel.Height = ClientSize.Height - m_infoPanel.Height;

            Form prompt = new Form();
            prompt.Text = "Статистика по пройденным тестам";
            prompt.Width = 600;
            prompt.Height = 590;
            prompt.FormBorderStyle = FormBorderStyle.Fixed3D;
            NumericUpDown inputBox = new NumericUpDown() { Left = 50, Top = 50, Width = 400 };
            prompt.Controls.Add(m_userPanel);
            prompt.ShowDialog();
        }

        private void DestroyAdminPanel()
        {
            if (m_adminPanel != null)
            {
                m_adminPanel.DestroyPanel();
                Controls.Remove(m_adminPanel);
                m_adminPanel = null;
            }
        }

        private void DestroyUserPanel()
        {
            if (m_userPanel != null)
            {
                m_userPanel.DestroyPanel();
                Controls.Remove(m_adminPanel);
                m_userPanel = null;
            }
        }

        private void DestroyQuestions()
        {
            if (m_questions != null)
            {
                m_questions.DestroyMenu();
                Controls.Remove(m_questions);
                m_questions = null;
            }
        }

        private void OnAdminAuth(String login)
        {
            DestroyUserPanel();
            DestroyQuestions();

            this.Visible = true;

            CreateInfoPanel();
            m_infoPanel.SwitchExtraComponentsVisible(false);
            m_infoPanel.SetAdminLogin(login);
            m_infoPanel.RemovePrevTestsButton();

            CreateAdminPanel(login);
        }

        private void OnUserAuth(UserInfo userInfo)
        {
            this.Visible = true;
            
            CreateMenu();

            string filePath = InfoSerializer.GetUserFilePath(userInfo.Guid.ToString());

            m_userInfo = userInfo;

            FillUserInfo(filePath);

            CreateInfoPanel();
            m_infoPanel.SetUserInfo(m_userInfo);
            m_infoPanel.SwitchExtraComponentsVisible(false);
            m_infoPanel.AddPrevTestsButton();
            m_beginTestTime = InfoSerializer.GetCurrentDateAndTime();
            m_beginTestTimestamp = InfoSerializer.GetCurrentTimestamp();
            //CreateUserPanel();
        }

        private void FillUserInfo(string filePath)
        {
            if (!File.Exists(filePath))
            {
                m_userInfo = InfoSerializer.InitNewUserInfo(m_userInfo);
            }
            else
            {
                m_userInfo = InfoSerializer.InitUserInfoFromFile(filePath, m_userInfo);
            }
        }

        private void ShowTestResult(int percentCholeric, int percentSanguine, int percentPhlegmatic, int percentMelancholiac)
        {
            string testResults = "У вас темперамент на " + percentCholeric + 
                                " % холерический, на " + percentSanguine + 
                                " % сангвинический, на " +percentPhlegmatic + 
                                " % флегматичный, на " + percentMelancholiac + 
                                " % меланхолический";
             

            MessageBox.Show(
                testResults,
                "Результаты теста",
                MessageBoxButtons.OK,
                MessageBoxIcon.Information
                );
        }

        private void StartTest()
        {
            m_infoPanel.SwitchExtraComponentsVisible(true);
        }


        private void CreateMenu()
        {
            if (this.InvokeRequired)
            {
                CreateMenuDelegate createMenuDelegate = new CreateMenuDelegate(CreateMenuItems);
                this.Invoke(createMenuDelegate);
            }
            else
            {
                CreateMenuItems();
            }
        }

        private void CreateMenuItems()
        {
            DestroyAdminPanel();

            m_questions = new belov_test.Questions();
            m_questions.TestPassed += new EventHandler(OnTestPassed);
            m_questions.Location = new Point((ClientRectangle.Width - m_questions.Width) / 2, belov_test.Questions.DEFAULT_LINE_DISTANCE);
            Controls.Add(m_questions);
        }

        private void OnTestPassed(object sender, EventArgs e)
        {
            ArrayList answers = m_questions.GetAnswers();
            int countPlusСholeric = 0;
            int countPlusSanguine = 0;
            int countPlusPhlegmatic = 0;
            int countPlusMelancholiac = 0;
            int countAll = 0;
            for (int i = 0; i < answers.Count; i++)
            {
                if (answers[i].Equals(1))
                {
                    ++countAll;
                    if (i < 20)
                    {
                        ++countPlusPhlegmatic;
                    }
                    else if (i < 40)
                    {
                        ++countPlusMelancholiac;
                    }
                    else if (i < 60)
                    {
                        ++countPlusСholeric;
                    }
                    else
                    {
                        ++countPlusSanguine;
                    }
                }
            }
            int percentCholeric = 0;
            int percentSanguine = 0;
            int percentPhlegmatic = 0;
            int percentMelancholiac = 0;
            if (countAll > 0)
            {
                percentCholeric = (int)Math.Floor(((double)countPlusСholeric / (double)countAll) * 100);
                percentSanguine = (int)Math.Floor(((double)countPlusSanguine / (double)countAll) * 100);
                percentPhlegmatic = (int)Math.Floor(((double)countPlusPhlegmatic / (double)countAll) * 100);
                percentMelancholiac = 100 - percentCholeric - percentSanguine - percentPhlegmatic;
            }
            
            TestResult result = new TestResult(percentCholeric, percentSanguine, percentPhlegmatic, percentMelancholiac);
            TimeSpan elapsedTime = DateTime.Now - m_beginTestTimestamp;
            result.Time = elapsedTime.Seconds;
            result.BeginTime = m_beginTestTime;
            result.EndTime = InfoSerializer.GetCurrentDateAndTime();

            m_userInfo.AddTestResult(result);

            ShowTestResult(percentCholeric, percentSanguine, percentPhlegmatic, percentMelancholiac);
            DestroyQuestions();
        }

        private void OnTestStart()
        {
            m_beginTestTime = InfoSerializer.GetCurrentDateAndTime();
        }

        private void CreateInfoPanel()
        {
            m_infoPanel = new InformationPanel();
            m_infoPanel.Width = ClientRectangle.Width;
            m_infoPanel.Height = InformationPanel.DEFAULT_HEIGHT;
            m_infoPanel.Location = new Point(0, ClientRectangle.Height - m_infoPanel.Height);
            m_infoPanel.ExitTest += new EventHandler(OnExitTest);
            m_infoPanel.ExitUserAccount += new EventHandler(OnExitAccount);
            m_infoPanel.ExitProgram += new EventHandler(OnExitProgram);
            m_infoPanel.RestartTest += new EventHandler(OnRestartTest);
            m_infoPanel.ShowPreviousTest += new EventHandler(OnShowPreviousTest);

            Controls.Add(m_infoPanel);
        }

        private void OnRestartTest(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                RestartTestDelegate restartTestDelegate = new RestartTestDelegate(RestartTest);
                this.Invoke(restartTestDelegate);
            }
            else
            {
                RestartTest();
            }
        }

        private void RestartTest()
        {
        }

        private void OnExitProgram(object sender, EventArgs e)
        {
            InfoSerializer.SaveUserInfo(m_userInfo);
        }

        private void OnExitAccount(object sender, EventArgs e)
        {
            InfoSerializer.SaveUserInfo(m_userInfo);

            DestroyAdminPanel();
            DestroyInfoPanel();

            this.Visible = false;

            CreateAuthForm();
        }

        private void OnExitTest(object sender, EventArgs e)
        {
            m_infoPanel.SwitchExtraComponentsVisible(false);
            CreateMenu();
        }

        private void DestroyInfoPanel()
        {
            if (m_infoPanel != null)
            {
                m_infoPanel.DestroyPanel();
                Controls.Remove(m_infoPanel);
                m_infoPanel = null;
            }
        }

        private void OnFormClosing(object sender, FormClosingEventArgs e)
        {
            InfoSerializer.SaveUserInfo(m_userInfo);
        }
    }
}
